package com.topisv.tms.utils.yto;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Set;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.topisv.tms.jms.vo.ConsignorMessage;
import com.topisv.tms.jms.vo.Ordeno;
import com.topisv.tms.jms.vo.OrdenoGoods;
import com.topisv.tms.utils.TimeUtil;
import com.topisv.tms.utils.http.HttpPost;

import net.ytoec.kernel.Sys;
import net.ytoec.kernel.YtoApiClient;
import net.ytoec.kernel.request.batchqueryrequest.BatchQueryOrder;
import net.ytoec.kernel.request.batchqueryrequest.BatchQueryRequest;
import net.ytoec.kernel.request.cancelorder.CancelOrderRequest;
import net.ytoec.kernel.request.createorder.CreateOrderItem;
import net.ytoec.kernel.request.createorder.CreateOrderRequest;
import net.ytoec.kernel.request.mailnorequest.MailNoRequest;
import net.ytoec.kernel.request.mailnorequest.confirm.MailNoRequestConfirm;
import net.ytoec.kernel.request.updatemailno.UpdateMailNoRequest;
import net.ytoec.kernel.response.Response;
import net.ytoec.kernel.response.batchqueryresponse.BatchQueryResponse;
import net.ytoec.kernel.response.batchqueryresponse.Order;
import net.ytoec.kernel.response.batchqueryresponse.Step;
import net.ytoec.kernel.response.mailnoresponse.MailNoResponse;
import net.ytoec.kernel.response.mailnoresponse.confirm.MailNoResponseComfirm;

/**
 * 圆通电子面单
 * 
 * @author Administrator
 * 
 */
public class YTOMailNoUtil {

	private static final Logger log = LoggerFactory.getLogger(YTOMailNoUtil.class);

	/**
	 * 取消订单
	 * @param apiUrl
	 * @param customerId
	 * @param clientId
	 * @param parternId
	 * @param txLogisticID
	 * @return
	 * @throws Exception
	 */
	public static Response cancelOrder(String apiUrl, String customerId,String clientId, String parternId, String txLogisticID)
			throws Exception {
		log.info("开始取消订单");
		log.info("apiUrl===" + apiUrl);
		log.info("customerId===" + customerId);
		log.info("clientId===" + clientId);
		log.info("parternId===" + parternId);
		log.info("txLogisticID===" + txLogisticID);

		System.out.println("开始取消订单");
		System.out.println("apiUrl===" + apiUrl);
		System.out.println("customerId===" + customerId);
		System.out.println("clientId===" + clientId);
		System.out.println("parternId===" + parternId);
		System.out.println("txLogisticID===" + txLogisticID);
		Response response = null;
		try {
			/*
			 * 封装请求信息
			 */
			CancelOrderRequest cancelOrderRequest = new CancelOrderRequest();
			cancelOrderRequest.setClientID(clientId);
			cancelOrderRequest.setInfoContent("WITHDRAW");
			cancelOrderRequest.setInfoType("INSTRUCTION");
			cancelOrderRequest.setLogisticProviderID("YTO");
			cancelOrderRequest.setRemark(Sys.randomChinese());
			cancelOrderRequest.setTxLogisticID(txLogisticID);

			cancelOrderRequest.setApiUrl(apiUrl);
			cancelOrderRequest.setClientID(clientId);
			cancelOrderRequest.setParternId(parternId);
			/*
			 * 打印返回信息
			 */
			response = YtoApiClient.cancelOrder(cancelOrderRequest);

		} catch (Exception e) {
			throw e;
		}

		log.info("取消订单返回值");
		log.info("response.getLogisticProviderID():"+ response.getLogisticProviderID());
		log.info("response.getReason():" + response.getReason());
		log.info("response.getSuccess():" + response.getSuccess());
		log.info("getTxLogisticID:" + response.getTxLogisticID());

		System.out.println("取消订单返回值");
		System.out.println("getReason:" + response.getReason());
		System.out.println("getLogisticProviderID:"+ response.getLogisticProviderID());
		System.out.println("getSuccess:" + response.getSuccess());
		System.out.println("getTxLogisticID:" + response.getTxLogisticID());
		return response;
	}

	private static List<CreateOrderRequest> getCreateOrderRequest(
			String customerId, ConsignorMessage consignor,
			List<Ordeno> ordenos) {
		List<CreateOrderRequest> requestOrders = new ArrayList<CreateOrderRequest>();
		for (Ordeno o : ordenos) {
			CreateOrderRequest cr = getCreateOrderRequest(consignor, o);
			cr.setCustomerId(customerId);
			requestOrders.add(cr);
		}
		return requestOrders;

	}

	private static CreateOrderRequest getCreateOrderRequest(
			ConsignorMessage consignor, Ordeno ordeno) {

		CreateOrderRequest requestOrder = new CreateOrderRequest();
		requestOrder.setLogisticProviderID("YTO");
		requestOrder.setTxLogisticID(ordeno.getOrdeno());// 必须传入可用数据
		requestOrder.setMailNo(ordeno.getExpressNo());// 必须传入可用数据
		requestOrder.setOrderType("1");// 订单类型(0-COD,1-普通订单,3-退货单)
		requestOrder.setGoodsValue(ordeno.getTotalPrice() + "");
		requestOrder.setType("1");
		requestOrder.setSendStartTime(TimeUtil.getNowDateString(new Date()));
		requestOrder.setSendEndTime(TimeUtil.getNowDateString(new Date()));
		requestOrder.setRemark("派友电子面单");
		requestOrder.setTotalValue(ordeno.getTotalPrice() + "");
		requestOrder.setServiceType("0");
		// 发送方
		requestOrder.getSender().setAddress(consignor.getAddress());
		requestOrder.getSender().setCity(consignor.getCity());
		requestOrder.getSender().setMobile(consignor.getMobile());
		requestOrder.getSender().setName(consignor.getName());
		requestOrder.getSender().setPhone(consignor.getPhone());
		requestOrder.getSender().setPostCode(consignor.getZipcode());
		requestOrder.getSender().setProv(consignor.getProvince());
		// 收货方
		requestOrder.getReceiver()
				.setAddress(ordeno.getReceiverAddress());
		requestOrder.getReceiver().setCity(ordeno.getReceiverCity());
		requestOrder.getReceiver().setMobile(ordeno.getReceiverMobile());
		requestOrder.getReceiver().setName(ordeno.getReceiverName());
		requestOrder.getReceiver().setPhone(ordeno.getReceiverPhone());
		requestOrder.getReceiver().setPostCode(ordeno.getReceiverZip());
		requestOrder.getReceiver().setProv(ordeno.getReceiverState());
		// 商品信息
		List<OrdenoGoods> ordenoGoods = ordeno.getOrdenoGoods();
		int length = ordenoGoods.size();
		Set<CreateOrderItem> items = requestOrder.getItems();
		for (int i = 0; i < length; i++) {
			OrdenoGoods sg = ordenoGoods.get(i);
			CreateOrderItem item = new CreateOrderItem();
			item.setItemName(sg.getSku());
			item.setItemValue(sg.getPrice() + "");
			item.setNumber(sg.getQuantity() + "");
			items.add(item);
		}
		return requestOrder;

	}

	/**
	 * 创建单个订单接口
	 * 
	 * @param apiUrl
	 * @param customerId
	 * @param clientId
	 * @param parternId
	 * @param consignor
	 * @param shippedOrder
	 */
	public static Response createOrder(String apiUrl, String customerId,
			String clientId, String parternId, ConsignorMessage consignor,
			Ordeno ordeno) {
		log.info("开始创建订单");
		log.info("apiUrl===" + apiUrl);
		log.info("customerId===" + customerId);
		log.info("clientId===" + clientId);
		log.info("parternId===" + parternId);

		System.out.println("开始创建订单");
		System.out.println("apiUrl===" + apiUrl);
		System.out.println("customerId===" + customerId);
		System.out.println("clientId===" + clientId);
		System.out.println("parternId===" + parternId);
		// System.out.println("shippedOrder==="+shippedOrder);
		/*
		 * 设置请求信息
		 */
		CreateOrderRequest requestOrder = getCreateOrderRequest(consignor,ordeno);
		requestOrder.setApiUrl(apiUrl);// 不会传到后台
		requestOrder.setParternId(parternId);// 不会传到后台
		requestOrder.setCustomerId(customerId);
		requestOrder.setClientID(clientId);
		/*
		 * 执行请求并打印返回结果 后台的返回的可能是格式化的XML也可能只有reason一个属性
		 */
		Response response = YtoApiClient.createOrder(requestOrder);
		log.info("创建订单时的返回信息");
		log.info("getReason:" + response.getReason());
		log.info("getLogisticProviderID:" + response.getLogisticProviderID());
		log.info("getSuccess:" + response.getSuccess());
		log.info("getTxLogisticID:" + response.getTxLogisticID());

		System.out.println("创建订单时的返回信息");
		System.out.println("getReason:" + response.getReason());
		System.out.println("getLogisticProviderID:"
				+ response.getLogisticProviderID());
		System.out.println("getSuccess:" + response.getSuccess());
		System.out.println("getTxLogisticID:" + response.getTxLogisticID());
		return response;
	}

	public static Response createOrder(String apiUrl, String customerId,
			String clientId, String parternId, ConsignorMessage consignor,
			List<Ordeno> ordenos) {
		log.info("开始创建订单");
		log.info("apiUrl===" + apiUrl);
		log.info("customerId===" + customerId);
		log.info("clientId===" + clientId);
		log.info("parternId===" + parternId);
		/*
		 * 设置请求信息
		 */
		List<CreateOrderRequest> requestOrders = getCreateOrderRequest(
				customerId, consignor, ordenos);
		/*
		 * 执行请求并打印返回结果 后台的返回的可能是格式化的XML也可能只有reason一个属性
		 */
		Response response = YtoApiClient.createOrder(apiUrl, parternId,
				clientId, requestOrders);
		log.info("开始创建订单");
		log.info("getReason:" + response.getReason());
		log.info("getLogisticProviderID:" + response.getLogisticProviderID());
		log.info("getSuccess:" + response.getSuccess());
		log.info("getTxLogisticID:" + response.getTxLogisticID());
		return response;
	}

	/**
	 * 申请面单号的方法
	 * 
	 * @param apiUrl
	 *            接口
	 * @param customerCode
	 * @param clientId
	 * @param parternId
	 * @return
	 * @throws Exception
	 */
	public static MailNoResponse mailNoRequest(String apiUrl,String customerCode, String clientId, String parternId)
			throws Exception {
		log.info("开始申请圆通电子面单号:第一次请求");
		log.info("apiUrl===" + apiUrl);
		log.info("customerCode===" + customerCode);
		log.info("clientId===" + clientId);
		log.info("parternId===" + parternId);

		System.out.println("开始申请圆通电子面单号");
		System.out.println("apiUrl===" + apiUrl);
		System.out.println("customerCode===" + customerCode);
		System.out.println("clientId===" + clientId);
		System.out.println("parternId===" + parternId);
		try {
			/*
			 * 第一次请求
			 */
			MailNoRequest mailNoRequest = new MailNoRequest();
			mailNoRequest.setCustomerCode(customerCode);
			mailNoRequest.setApiUrl(apiUrl);
			mailNoRequest.setClientId(clientId);
			mailNoRequest.setParternId(parternId);
			MailNoResponse mailNoResponse = YtoApiClient
					.mailNoRequest(mailNoRequest);
			// 请求失败
			if (!mailNoResponse.getSuccess()) {
				log.info("失败原因：" + mailNoResponse.getMessage());
				Sys.err("失败原因：" + mailNoResponse.getMessage());
				return mailNoResponse;
			}

			// 请求成功，打印相关信息
			String sequence = mailNoResponse.getSequence();// 服务器端生成的序列号，用于第2次请求
			String quantity = mailNoResponse.getQuantity();// 成功申请的数量

			/*
			 * 第二次请求
			 */
			MailNoRequestConfirm confirm = new MailNoRequestConfirm();
			confirm.setCustomerCode(customerCode);
			confirm.setSequence(sequence);
			confirm.setApiUrl(apiUrl);
			confirm.setClientID(clientId);
			confirm.setCustomerCode(customerCode);
			confirm.setParternId(parternId);

			log.info("开始申请圆通电子面单号:第二次请求");
			log.info("sequence===" + sequence);
			log.info("申请电子面单的数量===" + quantity);
			System.out.println("开始申请圆通电子面单号:第二次请求");
			System.out.println("sequence===" + sequence);
			System.out.println("申请电子面单的数量===" + quantity);
			MailNoResponseComfirm responseComfirm = YtoApiClient
					.mailNoRequestConfirm(confirm);
			if ("true".equals(responseComfirm.getSuccess())) {
				System.out.println("responseComfirm.getSuccess==="
						+ responseComfirm.getSuccess());
				return mailNoResponse;

			}
			return null;
		} catch (Exception e) {
			throw e;
		}
	}
	
	/**
	 * 更新电子面单号
	 * @param apiUrl
	 * @param clientId
	 * @param parternId
	 * @param mailNo
	 * @param txLogisticID
	 * @return
	 * @throws Exception
	 */
	public static Response updateMailNo(String apiUrl, String clientId, String parternId,String mailNo,String txLogisticID)throws Exception {
		log.info("更新电子面单号");
		log.info("apiUrl===" + apiUrl);
		log.info("clientId===" + clientId);
		log.info("parternId===" + parternId);
		log.info("mailNo===" + mailNo);
		log.info("txLogisticID===" + txLogisticID);

		System.out.println("更新电子面单号");
		System.out.println("apiUrl===" + apiUrl);
		System.out.println("clientId===" + clientId);
		System.out.println("parternId===" + parternId);
		System.out.println("mailNo===" + mailNo);
		System.out.println("txLogisticID===" + txLogisticID);
		Response response =null;
		try {
			/*
			 * 设置请求信息
			 */
			UpdateMailNoRequest updateInfo = new UpdateMailNoRequest();
			updateInfo.setClientID(clientId);
			updateInfo.setInfoType("INSTRUCTION");
			updateInfo.setInfoContent("UPDATE");
			updateInfo.setLogisticProviderID("YTO");
			updateInfo.setMailNo(mailNo);
			updateInfo.setRemark(Sys.randomChinese());
			updateInfo.setTxLogisticID(txLogisticID);
			updateInfo.setParternId(parternId);//不会传入后台
			updateInfo.setApiUrl(apiUrl);//不会传入后台
			/*
			 * 执行请求并打印结果
			 */
			response = YtoApiClient.updateMailNo(updateInfo);
			Sys.err(
					"getLogisticProviderID:"+response.getLogisticProviderID(),
					"getReason:"+response.getReason(),
					"getSuccess:"+response.getSuccess(),
					"getTxLogisticID:"+response.getTxLogisticID()
			);
			log.info("更新电子面单号返回值");
			log.info("getReason:" + response.getReason());
			log.info("getLogisticProviderID:" + response.getLogisticProviderID());
			log.info("getSuccess:" + response.getSuccess());
			log.info("getTxLogisticID:" + response.getTxLogisticID());
		} catch (Exception e) {
			throw e;
		}
		return response;
	}

	/**
	 * 查询一批电子面单流转状态信息
	 * @param apiUrl
	 * @param clientId
	 * @param parternId
	 * @param mailNos
	 * @return
	 * @throws Exception
	 */
	public static BatchQueryResponse orderFlowQuery(String apiUrl, String clientId, String parternId,List<String> mailNos)throws Exception{
		log.info("查询电子面单号流转信息");
		log.info("apiUrl===" + apiUrl);
		log.info("clientId===" + clientId);
		log.info("parternId===" + parternId);
		log.info("mailNos===" + mailNos);

		System.out.println("更新电子面单号");
		System.out.println("apiUrl===" + apiUrl);
		System.out.println("clientId===" + clientId);
		System.out.println("parternId===" + parternId);
		System.out.println("mailNos===" + mailNos);
		try {
			/*
			 * 设置查询信息
			 */
			BatchQueryRequest batchQueryRequest = new BatchQueryRequest();
			batchQueryRequest.setClientID(clientId);
			batchQueryRequest.setLogisticProviderID("YTO");
			batchQueryRequest.setParternId(parternId);//不会传入后台
			batchQueryRequest.setApiUrl(apiUrl);//不会传入后台
			
			for(String mailNo:mailNos){
				//添加一个运单号
				{
					BatchQueryOrder requestOrder = new BatchQueryOrder();
					requestOrder.setMailNo(mailNo);
					batchQueryRequest.getOrders().add(requestOrder);
				}
			}
		
			/*
			 * 执行查询并打印返回信息
			 */
			BatchQueryResponse response = YtoApiClient.orderFlowQuery(batchQueryRequest);
			Sys.err("开始某个订单的流转信息：");
			Sys.err("getLogisticProviderID:"+response.getLogisticProviderID());
			
			Set<Order> orders = response.getOrders();
			for (Order order : orders) {
				Sys.err("	打印一个订单的信息：");
				Sys.err(
						"getMailNo:"+order.getMailNo(),
						"getMailType:"+order.getMailType(),
						"getOrderStatus:"+order.getOrderStatus(),
						"getTxLogisticID:"+order.getTxLogisticID()
				);
				
				Set<Step> steps = order.getSteps();
				for (Step step : steps) {
					Sys.err("	该订单的一个步骤:");
					Sys.err(
							"getAcceptAddress:"+step.getAcceptAddress(),
							"getAcceptTime:"+step.getAcceptTime(),
							"getName:"+step.getName(),
							"getRemark:"+step.getRemark(),
							"getStatus:"+step.getStatus()
					);
				}
			}
			return response;
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 查询单个电子面单流转状态信息
	 * @param apiUrl
	 * @param clientId
	 * @param parternId
	 * @param mailNo
	 * @return
	 * @throws Exception
	 */
	public static BatchQueryResponse orderFlowQuery(String apiUrl, String clientId, String parternId,String mailNo)throws Exception{
		log.info("查询电子面单号流转信息");
		log.info("apiUrl===" + apiUrl);
		log.info("clientId===" + clientId);
		log.info("parternId===" + parternId);
		log.info("mailNo===" + mailNo);

		System.out.println("更新电子面单号");
		System.out.println("apiUrl===" + apiUrl);
		System.out.println("clientId===" + clientId);
		System.out.println("parternId===" + parternId);
		System.out.println("mailNo===" + mailNo);
		try {
			/*
			 * 设置查询信息
			 */
			BatchQueryRequest batchQueryRequest = new BatchQueryRequest();
			batchQueryRequest.setClientID(clientId);
			batchQueryRequest.setLogisticProviderID("YTO");
			batchQueryRequest.setParternId(parternId);//不会传入后台
			batchQueryRequest.setApiUrl(apiUrl);//不会传入后台
			
			//添加一个运单号
			BatchQueryOrder requestOrder = new BatchQueryOrder();
			requestOrder.setMailNo(mailNo);
			batchQueryRequest.getOrders().add(requestOrder);
		
			/*
			 * 执行查询并打印返回信息
			 */
			BatchQueryResponse response = YtoApiClient.orderFlowQuery(batchQueryRequest);
			Sys.err("开始某个订单的流转信息：");
			Sys.err("getLogisticProviderID:"+response.getLogisticProviderID());
			
			Set<Order> orders = response.getOrders();
			for (Order order : orders) {
				Sys.err("	打印一个订单的信息：");
				Sys.err(
						"getMailNo:"+order.getMailNo(),
						"getMailType:"+order.getMailType(),
						"getOrderStatus:"+order.getOrderStatus(),
						"getTxLogisticID:"+order.getTxLogisticID()
				);
				
				Set<Step> steps = order.getSteps();
				for (Step step : steps) {
					Sys.err("	该订单的一个步骤:");
					Sys.err(
							"getAcceptAddress:"+step.getAcceptAddress(),
							"getAcceptTime:"+step.getAcceptTime(),
							"getName:"+step.getName(),
							"getRemark:"+step.getRemark(),
							"getStatus:"+step.getStatus()
					);
				}
			}
			return response;
		} catch (Exception e) {
			throw e;
		}
	}
	
	/**
	 * 圆通面单查询接口
	 * @param apiUrl
	 * @param appKey
	 * @param secret
	 * @param userId
	 * @param mailNo
	 * @return
	 * @throws Exception
	 */
	public static String newOrderFlowQuery(String queryOrderUrl, String appKey, String secret,String userId,String mailNo)throws Exception{
		log.info("查询电子面单号流转信息");
		log.info("queryOrderUrl===" + queryOrderUrl);
		log.info("appKey===" + appKey);
		log.info("userId===" + userId);
		log.info("mailNo===" + mailNo);

		System.out.println("查询电子面单号流转信息");
		System.out.println("queryOrderUrl===" + queryOrderUrl);
		System.out.println("appKey===" + appKey);
		System.out.println("userId===" + userId);
		System.out.println("mailNo===" + mailNo);
		Date nowDate=new Date();
		try {
			StringBuffer param=new StringBuffer(secret);
			param.append("app_key"+appKey);
			param.append("formatjson");
			param.append("methodyto.Marketing.WaybillTrace");
			param.append("timestamp"+TimeUtil.getNowDateString(nowDate));
			param.append("user_id"+userId);
			param.append("v1.0");
			String sign=MD5Utils.md532(param.toString());//得到签名
			
			StringBuffer paramRequest=new StringBuffer("sign="+sign);
			paramRequest.append("&app_key="+appKey);
			paramRequest.append("&format=json");
			paramRequest.append("&method=yto.Marketing.WaybillTrace");
			paramRequest.append("&timestamp="+TimeUtil.getNowDateString(nowDate));
			paramRequest.append("&user_id="+userId);
			paramRequest.append("&v=1.0");
			paramRequest.append("&param=[{\"Number\":\""+mailNo+"\"}]");
			String result=HttpPost.pub(queryOrderUrl, paramRequest.toString());
			return result;
		} catch (Exception e) {
			throw e;
		}
	}
}
